package com.serviportales.serviquality.dao;

import java.io.Serializable;
import java.util.List;

import org.hibernate.FetchMode;
import org.hibernate.Query;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.serviportales.serviportales.dao.GenericHibernateDAO;
import com.serviportales.serviportales.utils.BeansUtils;
import com.serviportales.serviquality.model.Nodo;

@Repository
public class NodoDAO extends GenericHibernateDAO<Nodo> {

	private static final long serialVersionUID = 1L;

	@Override
	public DetachedCriteria getBasicDetachedCriteria(Nodo nodo) {
		DetachedCriteria criteria = DetachedCriteria.forClass(Nodo.class);

		if (nodo.getNodoPK() != null) {
			if (nodo.getNodoPK().getCodigo() != null) {
				criteria = criteria.add(Restrictions.ilike("nodoPK.codigo", nodo.getNodoPK().getCodigo(), MatchMode.ANYWHERE));
			}
			if (nodo.getNodoPK().getTipoNodo() != null && nodo.getNodoPK().getTipoNodo().getCodigo() != null) {
				criteria = criteria.setFetchMode("nodoPK.tipoNodo", FetchMode.JOIN);
				criteria = criteria.add(Restrictions.eq("nodoPK.tipoNodo.codigo", nodo.getNodoPK().getTipoNodo().getCodigo()));
			}
		}
		if (nodo.getNombre() != null) {
			criteria = criteria.add(Restrictions.ilike("nombre", nodo.getNombre(), MatchMode.ANYWHERE));
		}
		if (nodo.getDescripcion() != null) {
			criteria = criteria.add(Restrictions.ilike("descripcion", nodo.getDescripcion(), MatchMode.ANYWHERE));
		}
		if (nodo.getEstadoRegistro() != null && nodo.getEstadoRegistro().getCodigo() != null) {
			criteria = criteria.add(Restrictions.eq("estadoRegistro.codigo", nodo.getEstadoRegistro().getCodigo()));
		}
		return criteria;
	}

	public Nodo selectByID(Serializable codigo) {
		return getHibernateTemplate().get(Nodo.class, codigo);
	}

	@SuppressWarnings("unchecked")
	public List<Nodo> selectByNivel(Nodo nodo) throws Exception {
		boolean isEstadoRegistro = !BeansUtils.isEmpty(BeansUtils.getDatoAtributo(nodo, "estadoRegistro.codigo", String.class));
		String strQuery = "from Nodo as nodo " + //
				"join fetch nodo.nodoPK.tipoNodo " + //
				"where nodo.nodoPK.tipoNodo.nivel = :nivel";

		if (!BeansUtils.isEmpty(nodo.getNombre())) {
			strQuery += " and (upper(nodo.nombre) like upper(:nombre)) ";
		}
		if (isEstadoRegistro) {
			strQuery += " and (nodo.estadoRegistro.codigo = :estadoRegistro) ";
		}

		Query query = getSession().createQuery(strQuery);
		query.setInteger("nivel", nodo.getNodoPK().getTipoNodo().getNivel());
		if (!BeansUtils.isEmpty(nodo.getNombre())) {
			query.setString("nombre", '%' + nodo.getNombre() + '%');
		}
		if (isEstadoRegistro) {
			query.setString("estadoRegistro", nodo.getEstadoRegistro().getCodigo());
		}

		return query.list();
	}
}
